package com.acmen.easyapi.model;

import com.acmen.easyapi.annotation.ResParam;
import com.alibaba.fastjson.annotation.JSONField;
import com.acmen.easyapi.enums.BasicCode;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 响应信息主体
 *
 * @Author acmen
 */
public class Response<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    @ResParam(label = "编码")
    private int code;
    @ResParam(label = "是否成功")
    private boolean success;
    @ResParam(label = "消息")
    private String message;
    @ResParam(label = "日志追踪码")
    private String traceId;
    @ResParam(label = "业务数据")
    private T data;
    @ResParam(label = "扩展信息")
    private Extend extend;

    @JSONField(deserialize = false,serialize = false)
    private Map contextMap = new HashMap();



   public static class Extend{
        @ResParam(label = "开始时间")
        private String beginTime;
        @ResParam(label = "结束时间")
        private String endTime;
        @ResParam(label = "花费时间",note = "时间单位毫秒")
        private Long costTime;
        @ResParam(label = "异常信息",note = "当系统发生异常时，uat与ver环境或者公司人工请求访问会返回该信息")
        private String exception;

        public String getBeginTime() {
            return beginTime;
        }

        public void setBeginTime(String beginTime) {
            this.beginTime = beginTime;
        }

        public String getEndTime() {
            return endTime;
        }

        public void setEndTime(String endTime) {
            this.endTime = endTime;
        }

        public Long getCostTime() {
            return costTime;
        }

        public void setCostTime(Long costTime) {
            this.costTime = costTime;
        }

       public String getException() {
           return exception;
       }

       public Extend setException(String exception) {
           this.exception = exception;
           return this;
       }

       @Override
       public String toString() {
           return "Extend{" +
                   "beginTime='" + beginTime + '\'' +
                   ", endTime='" + endTime + '\'' +
                   ", costTime=" + costTime +
                   ", exception='" + exception + '\'' +
                   '}';
       }
   }


    public static <T> Response<T> build(Boolean success) {
        if(success){
            return success();
        }else{
            return failure();
        }
    }

    public static <T> Response<T> success() {
        Response<T> response = new Response<>();
        response.setCode(BasicCode.SUCCESS.getCode());
        response.setMessage(BasicCode.SUCCESS.getDesc());
        response.setSuccess(true);
        return response;
    }
    public static <T> Response<T> success(String message) {
        Response<T> response = new Response<>();
        response.setCode(BasicCode.SUCCESS.getCode());
        response.setMessage(message);
        response.setSuccess(true);
        return response;
    }

    public static <T> Response<T> failure() {
        Response<T> response = new Response<>();
        response.setCode(BasicCode.FAILURE.getCode());
        response.setMessage(BasicCode.FAILURE.getDesc());
        response.setSuccess(false);
        return response;
    }

    public static <T> Response<T> of(T data) {
        Response<T> response = new Response<>();
        response.setCode(BasicCode.SUCCESS.getCode());
        response.setMessage(BasicCode.SUCCESS.getDesc());
        response.setData(data);
        response.setSuccess(true);
        return response;
    }

    public static <T> Response<T> failure(String message) {
        Response<T> response = new Response<>();
        response.setCode(BasicCode.FAILURE.getCode());
        response.setMessage(message);
        response.setSuccess(false);
        return response;
    }

    public static <T> Response<T> failure(int code, String message) {
        Response<T> response = new Response<>();
        response.setCode(code);
        response.setMessage(message);
        response.setSuccess(false);
        return response;
    }

    public static <T> Response<T> failure(BasicCode basicCode) {
        Response<T> response = new Response<>();
        response.setCode(basicCode.getCode());
        response.setMessage(basicCode.getDesc());
        response.setSuccess(false);
        return response;
    }

    public T getData() {
        return data;
    }
    public T get() {
        return data;
    }


    public boolean isSuccess() {
        return success;
    }

    public Response<T> setSuccess(boolean success) {
        this.success = success;
        return this;
    }

    public int getCode() {
        return code;
    }

    public Response<T> setCode(int code) {
        this.code = code;
        return this;
    }

    public Response<T> setData(T data) {
        this.data = data;
        return this;
    }

    public String getMessage() {
        return message;
    }

    public Response<T> setMessage(String message) {
        this.message = message;
        return this;
    }

    @Override
    public String toString() {
        return "Response{" +
                "code=" + code +
                ", success=" + success +
                ", message='" + message + '\'' +
                ", traceId='" + traceId + '\'' +
                ", data=" + data +
                ", extend=" + extend +
                '}';
    }

    public String getTraceId() {
        return traceId;
    }

    public Response<T> setTraceId(String traceId) {
        this.traceId = traceId;
        return this;
    }

    public Extend getExtend() {
        return extend;
    }

    public void setExtend(Extend extend) {
        this.extend = extend;
    }

    public Map getContextMap() {
        return contextMap;
    }

    public Response<T> setContextMap(Map contextMap) {
        this.contextMap = contextMap;
        return this;
    }
}
